package com.account.core.service.impl;

import com.account.common.constant.Constants;
import com.account.common.exception.ServiceException;
import com.account.core.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class AccountAPI {

    @Resource
    RedisTemplate<String, String> redisTemplate;

    @Resource
    RestTemplate restTemplate;

    private static final String tokenKey = "api:token:stax";


    @Value("${stax.api.url}")
    private String baseUrl;

    @Value("${stax.api.email}")
    private String email;

    @Value("${stax.api.password}")
    private String password;

    private HttpHeaders getHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", this.getValidToken()); // 使用缓存的 token
        return headers;
    }

    private String getValidToken() {
        String cachedToken = redisTemplate.opsForValue().get(tokenKey);
        if (cachedToken != null && !cachedToken.isEmpty()) {
            return cachedToken;
        }

        // 调用生成 Token 的接口
        ResponseEntity<GenerateTokenResponse> response = generateToken();
        if (response.getStatusCode().is2xxSuccessful()) {
            GenerateTokenResponse body = response.getBody();
            String newToken = Constants.TOKEN_PREFIX + body.getJwt_token();

            // 缓存到 Redis，设置过期时间
            redisTemplate.opsForValue().set(tokenKey, newToken, 3500, TimeUnit.SECONDS);

            return newToken;
        } else {
            throw new RuntimeException("Failed to generate token");
        }
    }

    // 1. Generate Token
    private ResponseEntity<GenerateTokenResponse> generateToken() {
        log.info("Generating token for email: {}", email);
        try {
            String url = baseUrl + "/api/auth/authenticate";
            GenerateTokenRequest request = new GenerateTokenRequest();
            request.setEmail(email);
            request.setPassword(password);
            request.setExpiresInSeconds(3600);
            ResponseEntity<GenerateTokenResponse> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(request),
                    new ParameterizedTypeReference<GenerateTokenResponse>() {
                    }
            );
            log.info("Generated token response: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error generating token", e);
            throw e;
        }
    }

    // 2. Create User
    public ResponseEntity<ApiResponse<String>> createUser(UserCreateRequest user) {
        log.info("Creating user with request: {}", user);
        try {
            String url = baseUrl + "/api/users/create";

            ResponseEntity<ApiResponse<String>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(user, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResponse<String>>() {
                    }
            );
            log.info("User created successfully: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error creating user", e);
            throw new ServiceException(e.getMessage());
        }
    }

    // 3. Batch Create Users
    public ResponseEntity<ApiResultsResponse<List<ApiResponse<String>>>> batchCreateUsers(BatchCreateUsersRequest users) {
        log.info("Batch creating users with request: {}", users);
        try {
            String url = baseUrl + "/api/users/batch-create";
            ResponseEntity<ApiResultsResponse<List<ApiResponse<String>>>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(users, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResultsResponse<List<ApiResponse<String>>>>() {
                    }
            );
            log.info("Batch create users response: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error during batch create users", e);
            throw new ServiceException(e.getMessage());
        }
    }

    // 4. Update Password
    public ResponseEntity<ApiResponse<String>> updatePassword(UpdatePasswordRequest request) {
        log.info("Updating password for user: {}", request.getUserId());
        try {
            String url = baseUrl + "/api/users/update-password";
            ResponseEntity<ApiResponse<String>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(request, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResponse<String>>() {
                    }
            );
            log.info("Password updated: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error updating password", e);
            throw new ServiceException(e.getMessage());
        }
    }

    // 5. Delete User
    public ResponseEntity<ApiResponse<String>> deleteUser(DeleteUserRequest request) {
        log.info("Deleting user: {}", request.getUserId());
        try {
            String url = baseUrl + "/api/users/delete";
            ResponseEntity<ApiResponse<String>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(request, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResponse<String>>() {
                    }
            );
            log.info("User deleted: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error deleting user", e);
            throw new ServiceException(e.getMessage());
        }
    }

    // 6. Batch Delete Users
    public ResponseEntity<ApiResultsResponse<String>> batchDeleteUsers(BatchDeleteUsersRequest request) {
        log.info("Batch deleting users: {}", request.getUserIds());
        try {
            String url = baseUrl + "/api/users/batch-delete";
            ResponseEntity<ApiResultsResponse<String>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(request, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResultsResponse<String>>() {
                    }
            );
            log.info("Batch delete users response: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error during batch delete users", e);
            throw new ServiceException(e.getMessage());
        }
    }

    // 7. Suspend User
    public ResponseEntity<ApiResponse<String>> suspendUser(SuspendUserRequest request) {
        log.info("Suspending user: {}", request.getUserId());
        try {
            String url = baseUrl + "/api/users/suspend";
            ResponseEntity<ApiResponse<String>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(request, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResponse<String>>() {
                    }
            );
            log.info("User suspended: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error suspending user", e);
            throw new ServiceException(e.getMessage());
        }
    }

    // 8. Batch Suspend Users
    public ResponseEntity<ApiResultsResponse<String>> batchSuspendUsers(BatchSuspendUsersRequest request) {
        log.info("Batch suspending users: {}", request.getUserIds());
        try {
            String url = baseUrl + "/api/users/batch-suspend";
            ResponseEntity<ApiResultsResponse<String>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(request, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResultsResponse<String>>() {
                    }
            );
            log.info("Batch suspend users response: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error during batch suspend users", e);
            throw new ServiceException(e.getMessage());
        }
    }

    // 9. Update Usage Count
    public ResponseEntity<ApiResponse<String>> updateUsageCount(UpdateUsageCountRequest request) {
        log.info("Updating usage count for user: {}", request.getUserId());
        try {
            String url = baseUrl + "/api/users/update-usage-count";
            ResponseEntity<ApiResponse<String>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(request, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResponse<String>>() {
                    }
            );
            log.info("Usage count updated: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error updating usage count", e);
            throw new ServiceException(e.getMessage());
        }
    }

    // 10. Batch Update Usage Count
    public ResponseEntity<ApiResultsResponse<String>> batchUpdateUsageCount(BatchUpdateUsageCountRequest request) {
        log.info("Batch updating usage count: {}", request.getUpdates());
        try {
            String url = baseUrl + "/api/users/batch-update-usage-count";
            ResponseEntity<ApiResultsResponse<String>> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    new HttpEntity<>(request, this.getHeaders()),
                    new ParameterizedTypeReference<ApiResultsResponse<String>>() {
                    }
            );
            log.info("Batch usage count update response: {}", response.getBody());
            return response;
        } catch (Exception e) {
            log.error("Error during batch update usage count", e);
            throw new ServiceException(e.getMessage());
        }
    }
}
